﻿using System;
using System.Linq;
using Csla;
using Csla.Data;
using Csla.Validation;
using DemoCSLA.DalLinq;
using DemoCSLA.Libreria.Comandos;

namespace DemoCSLA.Libreria.Editables
{

    //******************************************
    //Clase generada por un Snippet de Erick Orlando © 2010
    //******************************************

    //Agregue aqui los using necesarios

    [Serializable()]
    public partial class Clientes : BusinessBase<Clientes>
    {

        #region Propiedades públicas

        private static PropertyInfo<string> m_IdCliente =
            RegisterProperty<string>(p => p.IdCliente);
        public string IdCliente
        {
            get { return GetProperty(m_IdCliente); }
            set { SetProperty(m_IdCliente, value); }
        }

        private static PropertyInfo<string> m_Nombres =
            RegisterProperty<string>(p => p.Nombres, "Nombres del Cliente");
        public string Nombres
        {
            get { return GetProperty(m_Nombres); }
            set { SetProperty(m_Nombres, value); }
        }


        private static PropertyInfo<string> m_Apellidos =
            RegisterProperty<string>(p => p.Apellidos, "Apellidos del Cliente");
        public string Apellidos
        {
            get { return GetProperty(m_Apellidos); }
            set { SetProperty(m_Apellidos, value); }
        }

        private static PropertyInfo<string> m_Correo =
            RegisterProperty<string>(p => p.Correo, "Correo Electrónico");
        public string Correo
        {
            get { return GetProperty(m_Correo); }
            set { SetProperty(m_Correo, value); }
        }

        private static PropertyInfo<int> m_Edad =
            RegisterProperty<int>(p => p.Edad, "Edad");
        public int Edad
        {
            get { return GetProperty(m_Edad); }
            set { SetProperty(m_Edad, value); }
        }

        #endregion //Propiedades públicas

        #region Reglas Validación

        protected override void AddBusinessRules()
        {
            ValidationRules.AddRule(CommonRules.StringRequired, m_Nombres);
            ValidationRules.AddRule(CommonRules.StringMaxLength,
                new CommonRules.MaxLengthRuleArgs(m_Nombres, 100));

            ValidationRules.AddRule(CommonRules.StringRequired, m_Apellidos);

            ValidationRules.AddRule(CommonRules.RegExMatch,
                new CommonRules.RegExRuleArgs(m_Correo, CommonRules.RegExPatterns.Email));

            ValidationRules.AddRule(CommonRules.MinValue<Int32>,
                  new CommonRules.MinValueRuleArgs<Int32>(m_Edad, 18));

            ValidationRules.AddRule(CorreoIsUniqueAsync, new AsyncRuleArgs(m_Correo));
        }

        private static void CorreoIsUniqueAsync(AsyncValidationRuleContext context)
        {
            var cmd = new CorreoDuplicado(context.PropertyValues["Correo"].ToString());
            var dp = new DataPortal<CorreoDuplicado>();

            dp.ExecuteCompleted += (o, e) =>
            {
                if (e.Error != null)
                {
                    context.OutArgs.Description = "Error al comprobar el correo" + e.Error.ToString();
                    context.OutArgs.Severity = RuleSeverity.Error;
                    context.OutArgs.Result = false;
                }
                else
                {
                    if (e.Object.Duplicado)
                    {
                        context.OutArgs.Description = "El Correo ya se utilizó anteriormente";
                        context.OutArgs.Severity = RuleSeverity.Error;
                        context.OutArgs.Result = false;
                    }
                    else
                    {
                        context.OutArgs.Result = true;
                    }
                }

                context.Complete();
                
            };
            dp.BeginExecute(cmd);
        }

        #endregion //Reglas Validación

        #region Métodos de instanciación

        private Clientes()
        { }

        public static Clientes NewClientes()
        { return DataPortal.Create<Clientes>(); }

        public static Clientes GetClientes(String IdCliente)
        {
            return DataPortal.Fetch<Clientes>
              (new SingleCriteria<Clientes, String>(IdCliente));
        }

        public static void DeleteClientes(String IdCliente)
        { DataPortal.Delete<Clientes>(new SingleCriteria<Clientes, String>(IdCliente)); }

        #endregion // Métodos de instanciación

        #region Data Access

        #region Data Access - Create

        [RunLocal()]
        protected new void DataPortal_Create()
        {//Inicializar las propiedades que crea conveniente
            LoadProperty(m_IdCliente, Guid.NewGuid().ToString());
            ValidationRules.CheckRules();
        }


        #endregion // Data Access - Create

        #region Data Access - Fetch

        private void DataPortal_Fetch(SingleCriteria<Clientes, String> criteria)
        {

            using (var ctx = ContextManager<DemoCSLADataContext>
                .GetManager(Contexto.DemoCSLA))
            {

                var dalCliente = Cliente.GetClienteById(ctx.DataContext, criteria.Value);

                if (dalCliente == null)
                    throw new
                     InvalidOperationException("No se puede leer este registro");

                LoadProperty(m_IdCliente, dalCliente.IdCliente);
                LoadProperty(m_Nombres, dalCliente.Nombres);
                LoadProperty(m_Apellidos, dalCliente.Apellidos);
                LoadProperty(m_Correo, dalCliente.Correo);
                LoadProperty(m_Edad, dalCliente.Edad);
            }

            MarkOld();
            ValidationRules.CheckRules();

        }

        #endregion //Data Access - Fetch

        #region Data Access - Insert

        [Transactional(TransactionalTypes.TransactionScope)]
        protected override void DataPortal_Insert()
        {

            using (var ctx = ContextManager<DemoCSLADataContext>
                .GetManager(Contexto.DemoCSLA))
            {
                var dalCliente = new Cliente();
                DoInsertUpdate(dalCliente);

                ctx.DataContext.Clientes.InsertOnSubmit(dalCliente);
                ctx.DataContext.SubmitChanges();
                MarkOld();
            }
        }

        #endregion //Data Access - Insert

        #region Data Access - Update

        [Transactional(TransactionalTypes.TransactionScope)]
        protected override void DataPortal_Update()
        {
            using (var ctx = ContextManager<DemoCSLADataContext>
                .GetManager(Contexto.DemoCSLA))
            {
                var q = Cliente.GetClienteById(ctx.DataContext,
                            ReadProperty(m_IdCliente));

                DoInsertUpdate(q);
                ctx.DataContext.SubmitChanges();
                MarkOld();
            }
        }

        #endregion //Data Access - Update

        #region DoInsertUpdate

        private void DoInsertUpdate(Cliente obj)
        {
            obj.IdCliente = ReadProperty(m_IdCliente);
            obj.Nombres = ReadProperty(m_Nombres);
            obj.Apellidos = ReadProperty(m_Apellidos);
            obj.Correo = ReadProperty(m_Correo);
            obj.Edad = ReadProperty(m_Edad);
        }

        #endregion //DoInsertUpdate

        #region Data Access - Delete

        [Transactional(TransactionalTypes.TransactionScope)]
        private void DataPortal_Delete(SingleCriteria<Clientes, String> criteria)
        {
            using (var ctx = ContextManager<DemoCSLADataContext>
                .GetManager(Contexto.DemoCSLA))
            {
                var q = Cliente.GetClienteById(ctx.DataContext, criteria.Value);
                ctx.DataContext.Clientes.DeleteOnSubmit(q);
                ctx.DataContext.SubmitChanges();
            }
        }

        #endregion // Data Access - Delete

        #endregion //Data Access

    }

}
